/**
 * Project 67th
 */


#ifndef _EVENTLOOP_H
#define _EVENTLOOP_H

#include "Acceptor.h"
#include "TcpConnection.h"
#include <unistd.h>
#include <sys/epoll.h>
#include <vector>
#include <map>
#include <mutex>
using std::vector;
using std::map;
using std::mutex;
using std::lock_guard;

using functor = function<void()>;

class EventLoop {
public: 

    /**
     * @param acceptor
     */
    EventLoop(Acceptor & acceptor);

    ~EventLoop();

    //循环是否进行
    void loop();
    void unloop();

    void setNewConnectionCallback(TcpConnectionCallback && cb);
    void setMessageCallback(TcpConnectionCallback && cb);
    void setCloseCallback(TcpConnectionCallback && cb);

    void doPendingFunctors();
    void runInLoop(functor && cb);
private:
    //封装epoll_create函数
    int createEpollFd();
    //将文件描述符放到红黑树上进行监听
    void addEpollFd(int fd);
    //文件描述符从红黑树上删除
    void delEpollFd(int fd);
    //封装epoll_wait
    void waitEpollFd();
    //listenfd就绪，处理新的连接
    void handleNewConnection();
    //connfd就绪，处理老的连接发送过来的数据
    void handleMessage(int fd);

    //创建eventfd，以及对这个文件描述符进行读、写操作
    int createEventFd();
    void handleRead();
    void wakeup();

private: 
    int _epfd;//epoll
    vector<struct epoll_event> _evtList;//就绪列表
    bool _isLooping;//循环标志位
    Acceptor & _acceptor;//
    map<int,TcpConnectionPtr> _conns;//connfd与TepConnection配对存储

    TcpConnectionCallback _onNewConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;

    int _evtfd; //代表计数器的文件描述符（用于线程间的通知）
    vector<functor> _pendings; //存放EventLoop要执行的任务
    mutex _mutex; //需要对上面的vector进行互斥访问
};

#endif //_EVENTLOOP_H
